package com.mo.xi.ge.info.help

import java.io.ByteArrayOutputStream
import java.security.KeyFactory
import java.security.spec.X509EncodedKeySpec
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec


/**
 * date:2024/1/27
 **/
object EncryptWrapper {

    fun aesEncrpt(content: String, key: String): String? {
        return infoTryCatch(null) {
            val contentBytes = content.toByteArray(Charsets.UTF_8)
            val keyBytes = key.toByteArray(Charsets.UTF_8)
            val encryptedBytes = cipherOperation(contentBytes, keyBytes)
            Base64Util.toBase64(encryptedBytes)
        }
    }

    private fun cipherOperation(
        contentBytes: ByteArray,
        keyBytes: ByteArray
    ): ByteArray? {
        return try {
            val secretKey = SecretKeySpec(keyBytes, "AES")
            val initParam: ByteArray =
                Base64Util.decode("QS0xNi1CeXRlLVN0cmluZw==")
            val ivParameterSpec = IvParameterSpec(initParam)
            val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
            cipher.doFinal(contentBytes)
        } catch (e: Exception) {
            null
        }
    }

    fun encryptSuper(entryptData: String, publicKey: String): ByteArray {
        val data = entryptData.toByteArray(Charsets.UTF_8)
        // 对数据加密
        val out = ByteArrayOutputStream()
        val encryptedData = try {
            val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
            val keyFactory = KeyFactory.getInstance("RSA")
                .generatePublic(X509EncodedKeySpec(Base64Util.decode(publicKey)))
            cipher.init(Cipher.ENCRYPT_MODE, keyFactory)
            val inputLen = data.size
            var offSet = 0
            var cache: ByteArray
            var i = 0
            val MAX_ENCRYPT_BLOCK = 117 //RSA最大加密明文大小
            // 对数据分段加密
            while (inputLen - offSet > 0) {
                cache = if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK)
                } else {
                    cipher.doFinal(data, offSet, inputLen - offSet)
                }
                out.write(cache, 0, cache.size)
                i++
                offSet = i * MAX_ENCRYPT_BLOCK
            }
            out.toByteArray()
        } catch (e: Exception) {
            byteArrayOf()
        }finally {
            out.close()
        }
        return encryptedData
    }
}
